﻿using System;

namespace Lr.Templating.FluentMapping
{
    /// <summary>
    /// Implementation for <see cref="IGenericTemplateMapping"/>,
    /// which defines a mapping between a template's placeholder and the value to generate for the placeholder.
    /// </summary>
    /// <typeparam name="TObject">The type the that will be taken into account when generating the value.</typeparam>
    internal class GenericTemplateMapping<TObject> : TemplateMappingBase, IGenericTemplateMapping<TObject>
    {
        /// <summary>
        /// Constructs a new <see cref="GenericTemplateMapping"/> instance.
        /// </summary>
        /// <param name="placeholder">The placeholder string.</param>
        /// <param name="value">The function, which returns a string, that will act as a replacement for the placeholder.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="placeholder"/> is null, empty or only exists of white spaces.</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="value"/> is null.</exception>
        internal GenericTemplateMapping(string placeholder, Func<TObject, string> value)
            : base(placeholder)
        {
            ThrowIf.Null(() => value);

            _value = value;
        }

        /// <summary>
        /// Function that generates the value that will act as a replacement for the placeholder.
        /// </summary>
        protected Func<TObject, string> Value { get { return _value; } }
        private readonly Func<TObject, string> _value;

        /// <summary>
        /// Calculates, and returns the value for the placeholder.
        /// </summary>
        /// <param name="object">The object to be taken into account when generating the value.</param>
        /// <returns>The value in the form of a string.</returns>
        public string GetValue(TObject @object)
        {
            return this.Value(@object);
        }
    }
}
